今天是雙十連假第一天~
修改CustomerService的@RequestParam(name="cid")
package com.tzu.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.tzu.domain.Customers;
import com.tzu.domain.CustomersRepo;
import com.tzu.domain.Message;
import com.tzu.domain.StatusMessage;
@RestController
public class CustomerService {
//Data Field注入JdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate;
//注入自訂Repository
@Autowired
private CustomersRepo customersRepo;
//傳遞一份Json進來 進行相對客戶更新作業
//方法參數 採用參數注入Parameter Injection
@PutMapping(path="/api/customers/update/rawdata",
consumes="application/json",produces="application/json")
public Message customersUpdate(@RequestBody Customers customers) {
Message message=new Message();
//更新客戶資料
String sql="update customers set companyname=?,address=?,phone=?,email=?,country=? where customerid=?";
try {
int affect=jdbcTemplate.update(sql,
//Lambda PreparedStatementSetter interface
(st)->{
//注入PreparedStatement物件,設定參數內容
st.setString(1, customers.getCompanyname());
st.setString(2, customers.getAddress());
st.setString(3, customers.getPhone());
st.setString(4, customers.getEmail());
st.setString(5, customers.getCountry());
st.setString(6, customers.getCustomerid());
}
);
if(affect>0) {
message.setCode(200);
message.setMsg("客戶資料更新成功");
}else {
message.setCode(200);
message.setMsg("查無該客戶資料更新");
}
}catch(DataAccessException ex) {
message.setCode(400);
message.setMsg("客戶資料更新失敗");
}
return message;
}
//刪除相對客戶資料
@DeleteMapping(path="/api/customers/delete/byid",produces="application/json")
public HttpEntity customersDelete(@RequestParam(name="cid") String customerid) {
System.out.println(customersRepo.getTemplate());
var result=customersRepo.delete(customerid);
HttpEntity<Object> httpEntity=null;
//判斷
if (result>0) {
//刪除成功
Message msg=new Message();
msg.setCode(200);
msg.setMsg("客戶資料刪除成功");
httpEntity=new HttpEntity<Object>(msg);
}else {
//刪除不到資料
StatusMessage msg=new StatusMessage();
msg.setCode(400);
msg.setMsg("沒有這一個客戶");
msg.setErrorCode("notfound");
httpEntity=new HttpEntity<Object>(msg);
}
return httpEntity;
}
}
更改了 customerDelete
方法的參數注入方式,現在它使用 @RequestParam
注解來接收客戶的 cid
參數,這是一個正確的做法,這樣可以通過 URL 的查詢參數傳遞值。
對刪除客戶資料和更新客戶資料的操作進行了很好的處理。這些更改提高了代碼的可讀性和正確性。
POSTMAN測試http://localhost:8080/api/customers/delete/byid?cid=C0002
顯示
改狀態碼的顯示:
再換一個目前有的測試http://localhost:8080/api/customers/delete/byid?cid=C0003
顯示200
看資料庫確實刪除
400是沒有問題
再修改一下
package com.tzu.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.tzu.domain.Customers;
import com.tzu.domain.CustomersRepo;
import com.tzu.domain.Message;
import com.tzu.domain.StatusMessage;
@RestController
public class CustomerService {
//Data Field注入JdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate;
//注入自訂Repository
@Autowired
private CustomersRepo customersRepo;
//傳遞一份Json進來 進行相對客戶更新作業
//方法參數 採用參數注入Parameter Injection
@PutMapping(path="/api/customers/update/rawdata",
consumes="application/json",produces="application/json")
public Message customersUpdate(@RequestBody Customers customers) {
Message message=new Message();
//更新客戶資料
String sql="update customers set companyname=?,address=?,phone=?,email=?,country=? where customerid=?";
try {
int affect=jdbcTemplate.update(sql,
//Lambda PreparedStatementSetter interface
(st)->{
//注入PreparedStatement物件,設定參數內容
st.setString(1, customers.getCompanyname());
st.setString(2, customers.getAddress());
st.setString(3, customers.getPhone());
st.setString(4, customers.getEmail());
st.setString(5, customers.getCountry());
st.setString(6, customers.getCustomerid());
}
);
if(affect>0) {
message.setCode(200);
message.setMsg("客戶資料更新成功");
}else {
message.setCode(200);
message.setMsg("查無該客戶資料更新");
}
}catch(DataAccessException ex) {
message.setCode(400);
message.setMsg("客戶資料更新失敗");
}
return message;
}
//刪除相對客戶資料
@DeleteMapping(path="/api/customers/delete/byid",produces="application/json")
public ResponseEntity customersDelete(@RequestParam(name="cid") String customerid) {
System.out.println(customersRepo.getTemplate());
var result=customersRepo.delete(customerid);
ResponseEntity<Object> responseEntity=null;
//判斷
if (result>0) {
//刪除成功
Message msg=new Message();
msg.setCode(200);
msg.setMsg("客戶資料刪除成功");
//reponseEntity=new reponseEntity<Object>(msg,HttpStatusCode.);
}else {
//刪除不到資料
StatusMessage msg=new StatusMessage();
msg.setCode(400);
msg.setMsg("沒有這一個客戶");
msg.setErrorCode("notfound");
}
return responseEntity;
}
}
已經引入了 ResponseEntity
並開始使用它來設置HTTP響應的狀態碼以及響應內容。不過,有一些誤植在您的代碼中,我已經修正了這些問題:
ResponseEntity
的構造函數中,HttpStatusCode 應該是 HttpStatus。msg
設置為 responseEntity
的內容。msg
設置為 responseEntity
的內容。以下是更新後的代碼:
@DeleteMapping(path="/api/customers/delete/byid", produces="application/json")
public ResponseEntity customersDelete(@RequestParam(name="cid") String customerid) {
System.out.println(customersRepo.getTemplate());
var result = customersRepo.delete(customerid);
ResponseEntity<Object> responseEntity = null;
// 判斷
if (result > 0) {
// 刪除成功
Message msg = new Message();
msg.setCode(200);
msg.setMsg("客戶資料刪除成功");
responseEntity = new ResponseEntity<>(msg, HttpStatus.OK);
} else {
// 刪除不到資料
StatusMessage msg = new StatusMessage();
msg.setCode(400);
msg.setMsg("沒有這一個客戶");
msg.setErrorCode("notfound");
responseEntity = new ResponseEntity<>(msg, HttpStatus.BAD_REQUEST);
}
return responseEntity;
}
代碼就應該並且它會返回相應的 HTTP 狀態碼和消息。
再修改
package com.tzu.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.tzu.domain.Customers;
import com.tzu.domain.CustomersRepo;
import com.tzu.domain.Message;
import com.tzu.domain.StatusMessage;
@RestController
public class CustomerService {
//Data Field注入JdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate;
//注入自訂Repository
@Autowired
private CustomersRepo customersRepo;
//傳遞一份Json進來 進行相對客戶更新作業
//方法參數 採用參數注入Parameter Injection
@PutMapping(path="/api/customers/update/rawdata",
consumes="application/json",produces="application/json")
public Message customersUpdate(@RequestBody Customers customers) {
Message message=new Message();
//更新客戶資料
String sql="update customers set companyname=?,address=?,phone=?,email=?,country=? where customerid=?";
try {
int affect=jdbcTemplate.update(sql,
//Lambda PreparedStatementSetter interface
(st)->{
//注入PreparedStatement物件,設定參數內容
st.setString(1, customers.getCompanyname());
st.setString(2, customers.getAddress());
st.setString(3, customers.getPhone());
st.setString(4, customers.getEmail());
st.setString(5, customers.getCountry());
st.setString(6, customers.getCustomerid());
}
);
if(affect>0) {
message.setCode(200);
message.setMsg("客戶資料更新成功");
}else {
message.setCode(200);
message.setMsg("查無該客戶資料更新");
}
}catch(DataAccessException ex) {
message.setCode(400);
message.setMsg("客戶資料更新失敗");
}
return message;
}
//刪除相對客戶資料
//使用傳遞客戶編號資訊架構 採用QueryString http://xxx.xxx,xxx/xxx/xxx?cid=value&...
@DeleteMapping(path="/api/customers/delete/byid",produces="application/json")
public ResponseEntity<Object> customersDelete(@RequestParam(name="cid") String customerid) {
System.out.println(customersRepo.getTemplate());
var result=customersRepo.delete(customerid);
ResponseEntity<Object> responseEntity=null;
//判斷
if (result>0) {
//刪除成功
Message msg=new Message();
msg.setCode(200);
msg.setMsg("客戶資料刪除成功");
responseEntity=new ResponseEntity<>(msg,HttpStatus.OK);
}else {
//刪除不到資料 回應Http status code-400
StatusMessage msg=new StatusMessage();
msg.setCode(400);
msg.setMsg("沒有這一個客戶");
msg.setErrorCode("notfound");
responseEntity=new ResponseEntity<>(msg,HttpStatus.BAD_REQUEST);
}
return responseEntity;
}
}
使用 ResponseEntity
和 HttpStatus
正確地處理了HTTP回應的情況。現在,customersUpdate
和 customersDelete
方法會返回相應的HTTP狀態碼以及消息,並且具有良好的錯誤處理。
目前資料庫顯示
POSTMAN測試http://localhost:8080/api/customers/delete/byid?cid=C0002
測試修改裡面有的C0003
再看資料庫
裡面空的~等等要測試要加入資料
INSERT INTO `sakila`.`customers` (`customerid`, `companyname`, `address`, `phone`, `email`, `country`) VALUES ('C0002', '中華電信', '台北市仁愛路', '02-12345678', 'cht@cht.com.tw', '中華民國');
INSERT INTO `sakila`.`customers` (`customerid`, `companyname`, `address`, `phone`, `email`, `country`) VALUES ('C0003', '中興工程', '台北市', '02-1233232', 'chen@cht.com.tw', '中華民國');
測試顯示200互相對應
測試顯示400互相對應
修改前端,配合Vue
目前設計的樣子,測試用http://localhost:8080/customers/allcustomers
修改後可以對應到POSTMAN測試http://localhost:8080/api/customers/delete/byid?cid=C0002的樣子,按F12就是開發者工具可以看到
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script th:src="@{/js/vue.min.js}"></script>
<script th:src="@{/js/jquery-3.6.1.min.js}"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<title>客戶清單與維護作業</title>
<!--設定樣式-->
<!--<style>
body{
background-color: lavenderblush;border: 2px;
}
#app{
background-color: aqua;
font-size: 16px;
color:darkblue;
}
.btnEdit{
background-color: black;
color:white;
}
#data tr:nth-child(odd){
background-color: coral;
color:black;
}
#data tr:nth-child(even){
background-color: rgb(220, 210, 156);
color:black;
}
</style>-->
<style>
thead{
background-color: lemonchiffon;
color:black;
font-size: 18px;
font-style: unset;
}
.rowHight{
background-color: bisque;
color:rgb(7, 1, 18);
}
</style>
</head>
<body id="body">
<script th:inline="javascript">
//定義變數 陣列內容???後端使用thymeleaf嵌入進來的[{,,,},{}]
var list=/*[[${data}]]*/ [];
//事件程序綁在標籤body標籤物件 onload事件上
//window.alert(document.getElementById('body'));
//標籤物件操作模組 DOM(Document Object Model)
document.getElementById('body').onload=function(){
//alert('我來了');
//參照標籤物件label
document.getElementById('counter').innerText='客戶記錄數:'+list.length;
}
</script>
<fieldset id="app">
<legend>客戶清單</legend>
<div>
<label id="counter"></label>
</div>
<table class="table table-dark table-hover">
<thead>
<tr>
<td>操作</td>
<td>客戶編號</td>
<td>公司行號</td>
<td>聯絡地址</td>
<td>連絡電話</td>
<td>EMAIL</td>
<td>國家別</td>
</tr>
</thead>
<!--借助JS MVVM Framework -->
<tbody id="data">
<tr v-for="(item,index) in customerList">
<td>
<!--按鈕事件程序 給Vue進行綁定function來執行-->
<!--如何知道這一個按鈕被觸發相對列???-->
<button class="btn btn-primary" v-on:click="editHandler" v-bind:accessKey="index">編輯</button>
<button class="btn btn-danger" v-on:click="deleteHandler" v-bind:accessKey="index">刪除</button>
</td>
<td>{{item.customerid}}</td>
<td>{{item.companyname}}</td>
<td>{{item.address}}</td>
<td>{{item.phone}}</td>
<td>{{item.email}}</td>
<td>{{item.country}}</td>
</tr>
</tbody>
</table>
<!--編輯相對客戶資料對話盒-->
<fieldset id="editDialog" style="display: none;">
<legend>客戶資料編輯</legend>
<table>
<tr>
<td>客戶編號</td>
<td><input type="text" v-model:value="curCustomers.customerid" readonly></td>
</tr>
<tr>
<td>公司行號</td>
<td><input type="text" v-model.lazy:value="curCustomers.companyname"></td>
</tr>
<tr>
<td>聯絡地址</td>
<td><input type="text" v-model:value="curCustomers.address"></td>
</tr>
<tr>
<td>連絡電話</td>
<td><input type="text" v-model:value="curCustomers.phone"></td>
</tr>
<tr>
<td>EMAIL</td>
<td><input type="text" v-model:value="curCustomers.email"></td>
</tr>
<tr>
<td>國家別</td>
<td><input type="text" v-model:value="curCustomers.country"></td>
</tr>
</table>
<h3>{{message}}</h3>
</fieldset>
<!--刪除對話盒-->
<fieldset id="deleteDialog" style="display: none;">
<h2>客戶編號:{{curCustomers.customerid}}</h2>
<h2>公司行號:{{curCustomers.companyname}}</h2>
</fieldset>
</fieldset>
<script>
//使用jquery selector挑選文件物件 .ready() 綁定聆聽已經完整下載之後引發事件
$(document).ready(
//事件程序
function(){
//alert('hi jquery');
}
);
//建構Vue物件
var app=new Vue(
{
//資料模組
data:{
customerList:[], //空陣列
rowIndex:-1, //挑選的相對順序
curCustomers:{}, //相對列 相對客戶物件
message:'', //異動資料回乎訊息
deleteService:'../api/customers/delete/byid?cid=%s'
},
//設定Vue支援共用程序 或者事件程序綁定來源
methods:{
//聆聽編輯按鈕被觸發
editHandler:function(e){
//reset
this.message='';
//取出按鈕的accessKey屬性 在一開始渲染畫面就設定相對資料列順序
let index=e.target.accessKey;
//透過順序對應Vue customerList取出相對的客戶資料
this.curCustomers=this.customerList[index];
//console.log(currentCustomers);
//HighLight資料的相對列
//先行移除原先挑選列的class
$('tbody tr').eq(app.rowIndex).removeClass('rowHight');
//使用選擇器挑選標籤 子標籤 eq(順序) 呼叫addClass Method動態加入class=""
$('tbody tr').eq(index).addClass('rowHight'); //選取tbody內所有的tr(所有列物件)
//將相對列進行管理
app.rowIndex=index;
//TODO 啟動對話盒 編輯相對列物件
$('#editDialog').dialog(
//初始化物件設定(抬頭/寬度/按鈕(s)/強佔式對話盒)
{
title:'客戶資料編輯',
modal:true,
width:360, //按鈕設計
buttons:[
{
text:'更新',
class:'btn btn-primary',
click:function(){
//TODO 進行非同步處理更新後端資料
//1建構一個XMLHttpRequest物件
let xhr=new XMLHttpRequest();
//2.設定開啟遠端服務位址
xhr.open('PUT','../api/customers/update/rawdata');
//沒有設定Request Header Content-Type:application/json
xhr.setRequestHeader("Content-Type","application/json")
//進行非同步 採用輪詢 必須設定callback程序進行處理
xhr.onreadystatechange=function(e){
if(xhr.readyState==4 && xhr.status==200){
//取出資料(JSON String)
let resultString=xhr.responseText;
//String反序列化成物件
let result=JSON.parse(resultString);
//使用app指定Vue物件成員
app.message=result.msg;//將訊息指派給Vue資料庫模組
console.log(resultString);
}
}
//JSON內容
let jsonString=JSON.stringify(app.curCustomers);
console.log(jsonString);
//正式送出去
xhr.send(jsonString);
}
},
{
text:'關閉',
class:'btn btn-danger',
click:function(){
//關閉對話盒
$('#editDialog').dialog('close');
}
}
]
}
);
//進行編輯畫面的渲染
},
//按鈕刪除事件
deleteHandler:function(e){
//1.取得相對被選取的記錄
let indexer=e.target.accessKey;
//取出相對客戶資料物件 指派給Vue資料模組
this.curCustomers=this.customerList[indexer];
console.log(this.curCustomers);
//Hight UI要設定
//先行移除原先挑選列的class
$('tbody tr').eq(app.rowIndex).removeClass('rowHight');
//使用選擇器挑選標籤 子標籤 eq(順序) 呼叫addClass Method動態加入class=""
$('tbody tr').eq(indexer).addClass('rowHight'); //選取tbody內所有的tr(所有列物件)
//將相對列進行管理
app.rowIndex=indexer;
//2.啟動對話盒 進行刪除作業
//使用jquery selector 挑選區塊
$('#deleteDialog').dialog(
//setting 設定JS物件
{
title:'客戶資料刪除',
//強佔式對話盒
modal:true,
width:400,
height:300,
//設定按鈕
buttons:[
{
text:'刪除',
click:function(){
let urlString=app.deleteService.replace("%s",app.curCustomers.customerid);
console.log(urlString);
},
class:'btn btn-danger'
},
{
text:'關閉',
click:function(){
//挑選對話區塊
$('#deleteDialog').dialog('close');
},
class:'btn btn-primary'
}
]
}
);
}
}
,
//當Vue完成掛載之後 引發事件..將JS變數list內容指派給Vue物件資料模組customerList
mounted:function(){
//將list變數內容指派給Vue資料物件模組customerList
this.customerList=list;
console.log(this.customerList);
}
}
);
//掛載到特定id去
app.$mount('#app');
</script>
</body>
</html>
這段HTML代碼主要涉及客戶清單的顯示、編輯和刪除操作,以及使用Vue.js實現相關的互動。以下是代碼的概要說明:
HTML head 部分:
主要的 HTML body 部分:
list
,然後將它指派給Vue實例的customerList
。Vue 實例的設定:
data
物件包含客戶清單 (customerList
)、當前選中的行 (rowIndex
)、當前編輯的客戶 (curCustomers
) 和異動訊息 (message
)。methods
中包含了處理編輯和刪除按鈕點擊事件的方法 (editHandler
和 deleteHandler
)。mounted
鉤子在Vue實例被成功掛載到DOM後執行,將客戶清單資料載入Vue實例中。HTML中使用Vue指令 (v-for
、v-on:click
、v-model
等) 來建立客戶清單、處理按鈕事件以及双向綁定。
最後,你還包含了一個刪除對話盒 (#deleteDialog
),當刪除按鈕點擊時,會顯示這個對話框。
這是一個具有Vue.js的客戶清單管理的基本樣板,允許你顯示、編輯和刪除客戶資料。
重新啟動後,畫面按刪除>再刪除
使用jQuery.ajax()並修改內容:顯示狀態
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script th:src="@{/js/vue.min.js}"></script>
<script th:src="@{/js/jquery-3.6.1.min.js}"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<title>客戶清單與維護作業</title>
<!--設定樣式-->
<!--<style>
body{
background-color: lavenderblush;border: 2px;
}
#app{
background-color: aqua;
font-size: 16px;
color:darkblue;
}
.btnEdit{
background-color: black;
color:white;
}
#data tr:nth-child(odd){
background-color: coral;
color:black;
}
#data tr:nth-child(even){
background-color: rgb(220, 210, 156);
color:black;
}
</style>-->
<style>
thead{
background-color: lemonchiffon;
color:black;
font-size: 18px;
font-style: unset;
}
.rowHight{
background-color: bisque;
color:rgb(7, 1, 18);
}
</style>
</head>
<body id="body">
<script th:inline="javascript">
//定義變數 陣列內容???後端使用thymeleaf嵌入進來的[{,,,},{}]
var list=/*[[${data}]]*/ [];
//事件程序綁在標籤body標籤物件 onload事件上
//window.alert(document.getElementById('body'));
//標籤物件操作模組 DOM(Document Object Model)
document.getElementById('body').onload=function(){
//alert('我來了');
//參照標籤物件label
document.getElementById('counter').innerText='客戶記錄數:'+list.length;
}
</script>
<fieldset id="app">
<legend>客戶清單</legend>
<div>
<label id="counter"></label>
</div>
<table class="table table-dark table-hover">
<thead>
<tr>
<td>操作</td>
<td>客戶編號</td>
<td>公司行號</td>
<td>聯絡地址</td>
<td>連絡電話</td>
<td>EMAIL</td>
<td>國家別</td>
</tr>
</thead>
<!--借助JS MVVM Framework -->
<tbody id="data">
<tr v-for="(item,index) in customerList">
<td>
<!--按鈕事件程序 給Vue進行綁定function來執行-->
<!--如何知道這一個按鈕被觸發相對列???-->
<button class="btn btn-primary" v-on:click="editHandler" v-bind:accessKey="index">編輯</button>
<button class="btn btn-danger" v-on:click="deleteHandler" v-bind:accessKey="index">刪除</button>
</td>
<td>{{item.customerid}}</td>
<td>{{item.companyname}}</td>
<td>{{item.address}}</td>
<td>{{item.phone}}</td>
<td>{{item.email}}</td>
<td>{{item.country}}</td>
</tr>
</tbody>
</table>
<!--編輯相對客戶資料對話盒-->
<fieldset id="editDialog" style="display: none;">
<legend>客戶資料編輯</legend>
<table>
<tr>
<td>客戶編號</td>
<td><input type="text" v-model:value="curCustomers.customerid" readonly></td>
</tr>
<tr>
<td>公司行號</td>
<td><input type="text" v-model.lazy:value="curCustomers.companyname"></td>
</tr>
<tr>
<td>聯絡地址</td>
<td><input type="text" v-model:value="curCustomers.address"></td>
</tr>
<tr>
<td>連絡電話</td>
<td><input type="text" v-model:value="curCustomers.phone"></td>
</tr>
<tr>
<td>EMAIL</td>
<td><input type="text" v-model:value="curCustomers.email"></td>
</tr>
<tr>
<td>國家別</td>
<td><input type="text" v-model:value="curCustomers.country"></td>
</tr>
</table>
<h3>{{message}}</h3>
</fieldset>
<!--刪除對話盒-->
<fieldset id="deleteDialog" style="display: none;">
<h2>客戶編號:{{curCustomers.customerid}}</h2>
<h2>公司行號:{{curCustomers.companyname}}</h2>
</fieldset>
</fieldset>
<script>
//使用jquery selector挑選文件物件 .ready() 綁定聆聽已經完整下載之後引發事件
$(document).ready(
//事件程序
function(){
//alert('hi jquery');
}
);
//建構Vue物件
var app=new Vue(
{
//資料模組
data:{
customerList:[], //空陣列
rowIndex:-1, //挑選的相對順序
curCustomers:{}, //相對列 相對客戶物件
message:'', //異動資料回乎訊息
deleteService:'../api/customers/delete/byid?cid=%s'
},
//設定Vue支援共用程序 或者事件程序綁定來源
methods:{
//聆聽編輯按鈕被觸發
editHandler:function(e){
//reset
this.message='';
//取出按鈕的accessKey屬性 在一開始渲染畫面就設定相對資料列順序
let index=e.target.accessKey;
//透過順序對應Vue customerList取出相對的客戶資料
this.curCustomers=this.customerList[index];
//console.log(currentCustomers);
//HighLight資料的相對列
//先行移除原先挑選列的class
$('tbody tr').eq(app.rowIndex).removeClass('rowHight');
//使用選擇器挑選標籤 子標籤 eq(順序) 呼叫addClass Method動態加入class=""
$('tbody tr').eq(index).addClass('rowHight'); //選取tbody內所有的tr(所有列物件)
//將相對列進行管理
app.rowIndex=index;
//TODO 啟動對話盒 編輯相對列物件
$('#editDialog').dialog(
//初始化物件設定(抬頭/寬度/按鈕(s)/強佔式對話盒)
{
title:'客戶資料編輯',
modal:true,
width:360, //按鈕設計
buttons:[
{
text:'更新',
class:'btn btn-primary',
click:function(){
//TODO 進行非同步處理更新後端資料
//1建構一個XMLHttpRequest物件
let xhr=new XMLHttpRequest();
//2.設定開啟遠端服務位址
xhr.open('PUT','../api/customers/update/rawdata');
//沒有設定Request Header Content-Type:application/json
xhr.setRequestHeader("Content-Type","application/json")
//進行非同步 採用輪詢 必須設定callback程序進行處理
xhr.onreadystatechange=function(e){
if(xhr.readyState==4 && xhr.status==200){
//取出資料(JSON String)
let resultString=xhr.responseText;
//String反序列化成物件
let result=JSON.parse(resultString);
//使用app指定Vue物件成員
app.message=result.msg;//將訊息指派給Vue資料庫模組
console.log(resultString);
}
}
//JSON內容
let jsonString=JSON.stringify(app.curCustomers);
console.log(jsonString);
//正式送出去
xhr.send(jsonString);
}
},
{
text:'關閉',
class:'btn btn-danger',
click:function(){
//關閉對話盒
$('#editDialog').dialog('close');
}
}
]
}
);
//進行編輯畫面的渲染
},
//按鈕刪除事件
deleteHandler:function(e){
//1.取得相對被選取的記錄
let indexer=e.target.accessKey;
//取出相對客戶資料物件 指派給Vue資料模組
this.curCustomers=this.customerList[indexer];
console.log(this.curCustomers);
//Hight UI要設定
//先行移除原先挑選列的class
$('tbody tr').eq(app.rowIndex).removeClass('rowHight');
//使用選擇器挑選標籤 子標籤 eq(順序) 呼叫addClass Method動態加入class=""
$('tbody tr').eq(indexer).addClass('rowHight'); //選取tbody內所有的tr(所有列物件)
//將相對列進行管理
app.rowIndex=indexer;
//2.啟動對話盒 進行刪除作業
//使用jquery selector 挑選區塊
$('#deleteDialog').dialog(
//setting 設定JS物件
{
title:'客戶資料刪除',
//強佔式對話盒
modal:true,
width:400,
height:300,
//設定按鈕
buttons:[
{
text:'刪除',
click:function(){
let urlString=app.deleteService.replace("%s",app.curCustomers.customerid);
console.log(urlString);
//ajax非同步呼喚
$.ajax(
//settings建構JS物件
{
url:urlString,
//請求方法
type:'DELETE',
//回應狀態碼2xx callback
success:function(result,status,xhr){
console.log(result);
},
//回應狀態碼是4xx or 5xx
error:function(xhr,status,error){
console.log(xhr);
}
}
);
},
class:'btn btn-danger'
},
{
text:'關閉',
click:function(){
//挑選對話區塊
$('#deleteDialog').dialog('close');
},
class:'btn btn-primary'
}
]
}
);
}
}
,
//當Vue完成掛載之後 引發事件..將JS變數list內容指派給Vue物件資料模組customerList
mounted:function(){
//將list變數內容指派給Vue資料物件模組customerList
this.customerList=list;
console.log(this.customerList);
}
}
);
//掛載到特定id去
app.$mount('#app');
</script>
</body>
</html>
這段HTML代碼看起來是一個客戶清單管理的網頁應用程式,使用了Vue.js和jQuery等技術。以下是對代碼的概要解釋:
HTML head 部分:這部分包含了引入必要的JavaScript和CSS資源,如Vue.js、jQuery、Bootstrap樣式等。同時,你還有一些設置<meta>
元素和頁面標題。
HTML body 部分:這是頁面的主要內容區域,包括一個<fieldset>
,裡面包含了客戶清單的標題和表格。
客戶清單表格:表格中包含了客戶資料的顯示。使用了Vue.js的v-for
指令,以便動態生成表格的內容。每一列包括了"編輯"和"刪除"按鈕,這些按鈕使用v-on:click
指令綁定到Vue實例中的editHandler
和deleteHandler
方法。
編輯和刪除對話框:這些對話框分別包含客戶資料的編輯和刪除表單。它們的可見性(style="display: none;"
)是通過Vue中的v-if
或者jQuery等來控制的。
Vue.js實例:在HTML底部,建立了一個Vue.js實例,這個實例控制著客戶資料和處理用戶互動。具體來說:
data
物件包含了客戶資料、當前選中的行、當前編輯的客戶資料和異動訊息。methods
包含了處理編輯和刪除事件的方法。mounted
鉤子用於在Vue實例掛載到DOM後,將資料載入Vue實例。整體而言,這個代碼是一個簡單的客戶清單管理應用程式,允許用戶查看、編輯和刪除客戶資料。Vue.js用於實現動態的前端互動,而jQuery則用於處理部分DOM操作和非同步請求。
測試http://localhost:8080/customers/allcustomers
顯示狀態
查看資料庫確實刪掉
再修改前端CODE:顯示刪除成功訊息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script th:src="@{/js/vue.min.js}"></script>
<script th:src="@{/js/jquery-3.6.1.min.js}"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<title>客戶清單與維護作業</title>
<!--設定樣式-->
<!--<style>
body{
background-color: lavenderblush;border: 2px;
}
#app{
background-color: aqua;
font-size: 16px;
color:darkblue;
}
.btnEdit{
background-color: black;
color:white;
}
#data tr:nth-child(odd){
background-color: coral;
color:black;
}
#data tr:nth-child(even){
background-color: rgb(220, 210, 156);
color:black;
}
</style>-->
<style>
thead{
background-color: lemonchiffon;
color:black;
font-size: 18px;
font-style: unset;
}
.rowHight{
background-color: bisque;
color:rgb(7, 1, 18);
}
</style>
</head>
<body id="body">
<script th:inline="javascript">
//定義變數 陣列內容???後端使用thymeleaf嵌入進來的[{,,,},{}]
var list=/*[[${data}]]*/ [];
//事件程序綁在標籤body標籤物件 onload事件上
//window.alert(document.getElementById('body'));
//標籤物件操作模組 DOM(Document Object Model)
document.getElementById('body').onload=function(){
//alert('我來了');
//參照標籤物件label
document.getElementById('counter').innerText='客戶記錄數:'+list.length;
}
</script>
<fieldset id="app">
<legend>客戶清單</legend>
<div>
<label id="counter"></label>
</div>
<table class="table table-dark table-hover">
<thead>
<tr>
<td>操作</td>
<td>客戶編號</td>
<td>公司行號</td>
<td>聯絡地址</td>
<td>連絡電話</td>
<td>EMAIL</td>
<td>國家別</td>
</tr>
</thead>
<!--借助JS MVVM Framework -->
<tbody id="data">
<tr v-for="(item,index) in customerList">
<td>
<!--按鈕事件程序 給Vue進行綁定function來執行-->
<!--如何知道這一個按鈕被觸發相對列???-->
<button class="btn btn-primary" v-on:click="editHandler" v-bind:accessKey="index">編輯</button>
<button class="btn btn-danger" v-on:click="deleteHandler" v-bind:accessKey="index">刪除</button>
</td>
<td>{{item.customerid}}</td>
<td>{{item.companyname}}</td>
<td>{{item.address}}</td>
<td>{{item.phone}}</td>
<td>{{item.email}}</td>
<td>{{item.country}}</td>
</tr>
</tbody>
</table>
<!--編輯相對客戶資料對話盒-->
<fieldset id="editDialog" style="display: none;">
<legend>客戶資料編輯</legend>
<table>
<tr>
<td>客戶編號</td>
<td><input type="text" v-model:value="curCustomers.customerid" readonly></td>
</tr>
<tr>
<td>公司行號</td>
<td><input type="text" v-model.lazy:value="curCustomers.companyname"></td>
</tr>
<tr>
<td>聯絡地址</td>
<td><input type="text" v-model:value="curCustomers.address"></td>
</tr>
<tr>
<td>連絡電話</td>
<td><input type="text" v-model:value="curCustomers.phone"></td>
</tr>
<tr>
<td>EMAIL</td>
<td><input type="text" v-model:value="curCustomers.email"></td>
</tr>
<tr>
<td>國家別</td>
<td><input type="text" v-model:value="curCustomers.country"></td>
</tr>
</table>
<h3>{{message}}</h3>
</fieldset>
<!--刪除對話盒-->
<fieldset id="deleteDialog" style="display: none;">
<h2>客戶編號:{{curCustomers.customerid}}</h2>
<h2>公司行號:{{curCustomers.companyname}}</h2>
<h3 class="text-primary">{{message}}</h3>
</fieldset>
</fieldset>
<script>
//使用jquery selector挑選文件物件 .ready() 綁定聆聽已經完整下載之後引發事件
$(document).ready(
//事件程序
function(){
//alert('hi jquery');
}
);
//建構Vue物件
var app=new Vue(
{
//資料模組
data:{
customerList:[], //空陣列
rowIndex:-1, //挑選的相對順序
curCustomers:{}, //相對列 相對客戶物件
message:'', //異動資料回乎訊息
deleteService:'../api/customers/delete/byid?cid=%s'
},
//設定Vue支援共用程序 或者事件程序綁定來源
methods:{
//聆聽編輯按鈕被觸發
editHandler:function(e){
//reset
this.message='';
//取出按鈕的accessKey屬性 在一開始渲染畫面就設定相對資料列順序
let index=e.target.accessKey;
//透過順序對應Vue customerList取出相對的客戶資料
this.curCustomers=this.customerList[index];
//console.log(currentCustomers);
//HighLight資料的相對列
//先行移除原先挑選列的class
$('tbody tr').eq(app.rowIndex).removeClass('rowHight');
//使用選擇器挑選標籤 子標籤 eq(順序) 呼叫addClass Method動態加入class=""
$('tbody tr').eq(index).addClass('rowHight'); //選取tbody內所有的tr(所有列物件)
//將相對列進行管理
app.rowIndex=index;
//TODO 啟動對話盒 編輯相對列物件
$('#editDialog').dialog(
//初始化物件設定(抬頭/寬度/按鈕(s)/強佔式對話盒)
{
title:'客戶資料編輯',
modal:true,
width:360, //按鈕設計
buttons:[
{
text:'更新',
class:'btn btn-primary',
click:function(){
//TODO 進行非同步處理更新後端資料
//1建構一個XMLHttpRequest物件
let xhr=new XMLHttpRequest();
//2.設定開啟遠端服務位址
xhr.open('PUT','../api/customers/update/rawdata');
//沒有設定Request Header Content-Type:application/json
xhr.setRequestHeader("Content-Type","application/json")
//進行非同步 採用輪詢 必須設定callback程序進行處理
xhr.onreadystatechange=function(e){
if(xhr.readyState==4 && xhr.status==200){
//取出資料(JSON String)
let resultString=xhr.responseText;
//String反序列化成物件
let result=JSON.parse(resultString);
//使用app指定Vue物件成員
app.message=result.msg;//將訊息指派給Vue資料庫模組
console.log(resultString);
}
}
//JSON內容
let jsonString=JSON.stringify(app.curCustomers);
console.log(jsonString);
//正式送出去
xhr.send(jsonString);
}
},
{
text:'關閉',
class:'btn btn-danger',
click:function(){
//關閉對話盒
$('#editDialog').dialog('close');
}
}
]
}
);
//進行編輯畫面的渲染
},
//按鈕刪除事件
deleteHandler:function(e){
//1.取得相對被選取的記錄
let indexer=e.target.accessKey;
//取出相對客戶資料物件 指派給Vue資料模組
this.curCustomers=this.customerList[indexer];
console.log(this.curCustomers);
//Hight UI要設定
//先行移除原先挑選列的class
$('tbody tr').eq(app.rowIndex).removeClass('rowHight');
//使用選擇器挑選標籤 子標籤 eq(順序) 呼叫addClass Method動態加入class=""
$('tbody tr').eq(indexer).addClass('rowHight'); //選取tbody內所有的tr(所有列物件)
//將相對列進行管理
app.rowIndex=indexer;
//2.啟動對話盒 進行刪除作業
//使用jquery selector 挑選區塊
$('#deleteDialog').dialog(
//setting 設定JS物件
{
title:'客戶資料刪除',
//強佔式對話盒
modal:true,
width:400,
height:300,
//設定按鈕
buttons:[
{
text:'刪除',
click:function(){
let urlString=app.deleteService.replace("%s",app.curCustomers.customerid);
console.log(urlString);
//ajax非同步呼喚
$.ajax(
//settings建構JS物件
{
url:urlString,
//請求方法
type:'DELETE',
//回應狀態碼2xx callback
success:function(result,status,xhr){
console.log(result);
app.message=result.msg;
},
//回應狀態碼是4xx or 5xx
error:function(xhr,status,error){
console.log(xhr);
let json=xhr.responseJSON;
app.message=json.msg;
}
}
);
},
class:'btn btn-danger'
},
{
text:'關閉',
click:function(){
//挑選對話區塊
$('#deleteDialog').dialog('close');
},
class:'btn btn-primary'
}
]
}
);
}
}
,
//當Vue完成掛載之後 引發事件..將JS變數list內容指派給Vue物件資料模組customerList
mounted:function(){
//將list變數內容指派給Vue資料物件模組customerList
this.customerList=list;
console.log(this.customerList);
}
}
);
//掛載到特定id去
app.$mount('#app');
</script>
</body>
</html>
這段HTML代碼似乎是一個客戶清單管理的網頁應用程式,使用了Vue.js和jQuery等技術。以下是對代碼的概要解釋:
HTML head 部分:這裡包含了一些<meta>
標籤來設定字符集和頁面視口。它也引入了一些JavaScript庫,如Vue.js和jQuery,以及一些CSS樣式表,如Bootstrap的CSS。
HTML body 部分:這是網頁的主要內容區域,包括一個<fieldset>
,裡面有客戶清單的標題和表格。
客戶清單表格:這個表格中包含了客戶資料的顯示。使用了Vue.js的v-for
指令,以便動態生成表格的內容。每一列包括了"編輯"和"刪除"按鈕,這些按鈕使用v-on:click
指令綁定到Vue實例中的editHandler
和deleteHandler
方法。
編輯和刪除對話框:這些對話框分別包含客戶資料的編輯和刪除表單。它們的可見性(style="display: none;"
)是通過Vue中的v-if
或jQuery等來控制的。
Vue.js實例:在HTML底部,建立了一個Vue.js實例,這個實例控制客戶資料和處理用戶互動。具體來說:
data
物件包含了客戶資料、當前選中的行、當前編輯的客戶資料和異動訊息。methods
包含了處理編輯和刪除事件的方法。mounted
鉤子用於在Vue實例掛載到DOM後,將資料載入Vue實例。總之,這個代碼是一個簡單的客戶清單管理應用程式,允許用戶查看、編輯和刪除客戶資料。Vue.js用於實現動態的前端互動,而jQuery則用於處理部分DOM操作和非同步請求。
測試http://localhost:8080/customers/allcustomers
顯示狀態
資料庫確實也沒有
如果沒資料了~再鍵入
INSERT INTO `sakila`.`customers` (`customerid`, `companyname`, `address`, `phone`, `email`, `country`) VALUES ('C0002', '中華電信', '台北市仁愛路', '02-12345678', 'cht@cht.com.tw', '中華民國');
INSERT INTO `sakila`.`customers` (`customerid`, `companyname`, `address`, `phone`, `email`, `country`) VALUES ('C0003', '中興工程', '台北市', '02-1233232', 'chen@cht.com.tw', '中華民國');
**臺北市資料大平臺:**https://data.taipei/
搜尋Ubike
https://data.taipei/dataset/detail?id=c6bc8aed-557d-41d5-bfb1-8da24f78f2fb
往下滑按下載可以看到裡面詳細資料
裡面資料:https://tcgbusfs.blob.core.windows.net/dotapp/youbike/v2/youbike_immediate.json
用POSTMAN取資料https://tcgbusfs.blob.core.windows.net/dotapp/youbike/v2/youbike_immediate.json
再新增檔案UbikeService.java:再修改前端CODE做服務串接,REST Control
package com.tzu.service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
//Ubike服務
@RestController
public class UbikeService {
//服務 提供輸入區域 找出即時資訊
@GetMapping(path="/api/ubike/{area}/rawdata",produces="application/json")
public String ubikeQry(@PathVariable(name="area") String sarea) {
return sarea;
}
}
這段程式碼是一個簡單的Spring Boot應用程式中的RESTful Web服務,它提供了一個Ubike服務。讓我解釋一下這個程式碼的關鍵部分:
@RestController
:這是Spring框架的註釋,它表明這個類是一個RESTful Web服務的控制器。它將該類標記為處理HTTP請求的控制器。
@GetMapping
:這是Spring框架的註釋,它用於映射HTTP GET請求到相應的方法。在這個例子中,@GetMapping
用於映射到 /api/ubike/{area}/rawdata
這個路徑。
@PathVariable
:這是Spring框架的註釋,它用於將URI中的模板變數映射到方法的參數。在這個例子中,@PathVariable
用於將 {area}
映射到方法的 sarea
參數。
public String ubikeQry(@PathVariable(name="area") String sarea)
:這是處理HTTP GET請求的方法。它接受一個名為 sarea
的參數,這個參數的值來自URI中的 {area}
。這個